// Debug functions
//

#ifndef __DEBUG_H__
#define __DEBUG_H__

#ifdef __cplusplus
extern "C" {
#endif

// NOTE: set to 1 to keep assert even in non debug version
#define __KEEP_ASSERT_ALWAYS__	0

#undef LOG
#undef TRACE
#undef ASSERT
#undef VERIFY

/////////////////////////////////////////////////////////////////////////////
// Basic debug functions

// Terminate the calling process after cleanup
void    d_exit(void);

// Send a formatted string to a output location
void	d_trace(char *format,...);

// Display a diagnostic message
// return	0 if user continued
//			1 if user aborted
int 	d_report(const char *file, int line, const char *literal);

#ifdef _DEBUG
int		d_OpenDbgLog(void);
void	d_CloseDbgLog(void);
#endif

// Cause a breakpoint exception to debug
#ifdef WIN_PC
#define d_break()	__asm { int 3 }
#else
#define d_break()	d_exit()
#endif

// Set callback function when d_report occurred
void	d_set_report_callback(void (*cb)(char *));


//////////////////////////////////////////////////////////////////////////////
// Macros		

// Send a formatted string to a debug monitor
#define LOG 				d_trace

// Evaluate an expression and generate a report when the result is FALSE(0)
#define ASSERT_ALWAYS(exp)	if (!(exp) && d_report(__FILE__,__LINE__,#exp)) \
								d_break();
#if defined WIN_CE

	#define TRACE			d_trace 
	#define ASSERT_(exp)	ASSERT_ALWAYS(exp)
 
#elif defined _DEBUG || __KEEP_ASSERT_ALWAYS__

    // This is similar to LOG except it does nothing in release build.
    #define TRACE           d_trace 
	
	// This is similar to ASSERT_ALWAYS except it does nothing in release build.
	#define ASSERT(exp)		ASSERT_ALWAYS(exp) 

    // This is similar to ASSERT_ALWAYS except it expands its parameter in release
	// build. the expression will evaluate always but only generate the
	// report in debug build.
    #define VERIFY(exp)	    ASSERT_ALWAYS(exp)

#else   /* !_DEBUG */

	#define TRACE			1?0:d_trace	// do nothing
    #define ASSERT(exp)		((void) 0)	// do nothing
    #define VERIFY(exp)		(exp)		// expand its paramete

#endif  /* _DEBUG */

/* Use ASSERT_DEBUG rather then ASSERT for more meaning */
#ifdef WIN_CE
#define ASSERT_DEBUG(exp)   ASSERT_(exp)
#else
#define ASSERT_DEBUG(exp)   ASSERT(exp)
#endif

#ifdef __cplusplus
}
#endif

#endif	// __DEBUG_H__
